package com.sihai.ehr.service.impl;

import com.sihai.core.*;
import com.sihai.ehr.model.biz.*;
import com.sihai.ehr.model.sys.AuditStatus;
import com.sihai.ehr.repository.AuditingRepository;
import com.sihai.ehr.service.JobSpecificationService;
import com.sihai.ehr.web.pojo.JobSpecificationPojo;
import org.apache.commons.lang.xwork.StringUtils;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author: xiao
 * @since: 12-6-9 上午9:26
 */
@Service("jobSpecificationService")
public class JobSpecificationServiceImpl implements JobSpecificationService {
    @Resource
    private DataAccessor dataAccessor;

    @Resource
    private AuditingRepository auditingRepository;

    @Override
    public JobSpecification get(Long id) {
        if(id == null){
            return null;
        }
        return dataAccessor.get(JobSpecification.class, id);
    }

    @Override
    public void save(JobSpecification jobSpecification) {
        if(jobSpecification == null){
            return;
        }

        boolean isNew = jobSpecification.getId() == null || jobSpecification.getId() == 0;
        
        List<JobSpecificationProject> projects = jobSpecification.getProjects();

        jobSpecification.setProjects(null);
        dataAccessor.save(jobSpecification);

        if(projects != null && !projects.isEmpty()){
            for(JobSpecificationProject project : projects){
                project.setJobSpecification(jobSpecification);
                dataAccessor.saveOrUpdate(project);
            }
        }

        jobSpecification.setProjects(projects);
        dataAccessor.save(jobSpecification);

        if(isNew){
            saveJobSpecificationAuditings(jobSpecification, 1);
        }
    }

    @Override
    public LimitedList<JobSpecification> findByDuty(Long id, Limit limit, Sorter sorter) {
        if(id == null){
            return null;
        }

        return dataAccessor.findByHql(JobSpecification.class, "from JobSpecification j where j.cancel <> 1 and j.duty.id = ?", new Object[]{id}, limit, sorter);
    }

    @Override
    public void remove(final String jobSpecificationIds) {
        if(StringUtils.isBlank(jobSpecificationIds)){
            return;
        }

        dataAccessor.batchUpdate(new QueryCreator() {
            @Override
            public Query createQuery(Session session) {
                return session.createQuery(String.format("update JobSpecification j set j.cancel = 1 where j.id in (%s)", jobSpecificationIds));
            }
        });
    }

    //查询工作说明书(设置页面列表 right join)(仅适用工作说明书设置页面列表)
    @Override
    public LimitedList<JobSpecificationPojo> findByOrganization(Long organizationId, Limit limit, Sorter sorter) {
        //LimitedList<Object> objs = dataAccessor.findByHql(Object.class, "select d.id, d.dutyName, d.organization.employeeCount, j.id from JobSpecification j right join j.duty d where d.organization.id = ?", new Object[]{organizationId}, limit, sorter);
        return dataAccessor.findByHql(JobSpecificationPojo.class, "select new com.sihai.ehr.web.pojo.JobSpecificationPojo(d.id, d.dutyName, d.organization.employeeCount, j.id, j.taskContent, j.auditStatus) from JobSpecification j right join j.duty d where d.cancel=0 and d.organization.id = ?", new Object[]{organizationId}, limit, sorter);
    }

    @Override
    public List<JobSpecificationProject> getProjects(Long id) {
        return dataAccessor.findByHql(JobSpecificationProject.class, "from JobSpecificationProject p where p.jobSpecification.id = ?", new Object[]{id}, null, null);
    }

    @Override
    public LimitedList<JobSpecification> findByOrganizationAndStatus(final Long organizationId, final AuditStatus[] status, Limit limit, Sorter sorter) {
        //return dataAccessor.findByHql(JobSpecification.class, "from JobSpecification j where j.cancel <> 1 and j.auditStatus=? and j.duty.organization.id = ?", new Object[]{status, organizationId}, limit, sorter);
        return dataAccessor.findByQuery(JobSpecification.class, new QueryCreator() {
            @Override
            public Query createQuery(Session session) {
                Query query = session.createQuery("from JobSpecification j where j.cancel <> 1 and j.auditStatus in (:auditStatus) and j.duty.organization.id = :organizationId");
                query.setParameter("organizationId", organizationId);
                query.setParameterList("auditStatus", status);
                return query;
            }
        }, limit, sorter);
    }

    //查询工作说明书审核流程记录
    @Override
    public List<List<JobSpecificationAuditing>> findJobSpecificationAuditing(Long id) {
        return auditingRepository.findByHql(JobSpecificationAuditing.class, "from JobSpecificationAuditing ja where ja.jobSpecification.id = ?", new Object[]{id});
    }

    @Override
    public JobSpecificationProject getProject(Long id) {
        if(id == null){
            return null;
        }
        return dataAccessor.get(JobSpecificationProject.class, id);
    }

    @Override
    public void saveProject(JobSpecificationProject project) {
        if(project == null){
            return;
        }
        dataAccessor.save(project);
    }

    @Override
    public void removeProject(Long id) {
        if(id == null || id < 0){
            return;
        }
        dataAccessor.delete(dataAccessor.get(JobSpecificationProject.class, id));
    }

    @Override
    public void saveJobSpecificationAuditingProcess(JobSpecification jobSpecification) {
        saveJobSpecificationAuditings(jobSpecification, 1);
    }

    //创建审核流程
    private void saveJobSpecificationAuditings(JobSpecification jobSpecification, int auditNo) {
        auditingRepository.saveAuditingProcess(jobSpecification, auditNo);
    }
}
